package com.tungse.study.mini_spring;

import com.tungse.study.mini_spring.annotation.MyAutowired;
import com.tungse.study.mini_spring.annotation.MyComponent;
import com.tungse.study.mini_spring.annotation.MyPostConstruct;

import javax.validation.constraints.NotNull;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Tungse
 */
public class BeanDefinition {

    private final String name;
    private final Constructor<?> constructor;
    private final Method postConstructMethod;
    private final List<Field> autowiredFields;
    private final Class<?> beanType;


    public BeanDefinition(@NotNull Class<?> type) {
        this.beanType = type;
        MyComponent component = type.getDeclaredAnnotation(MyComponent.class);
        this.name = component.name().isEmpty() ? type.getSimpleName() : component.name();
        try {
            this.constructor = type.getConstructor();
            this.postConstructMethod = Arrays.stream(type.getDeclaredMethods())
                    .filter(method -> method.isAnnotationPresent(MyPostConstruct.class))
                    .findFirst().orElse(null);
            autowiredFields = Arrays.stream(type.getDeclaredFields()).filter(e -> e.isAnnotationPresent(MyAutowired.class)).collect(Collectors.toList());

        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
    }


    public String getName() {
        return name;
    }

    public Constructor<?> getConstructor() {
        return constructor;
    }

    public Method getPostConstructMethod() {
        return postConstructMethod;
    }

    public List<Field> getAutowiredFields() {
        return autowiredFields;
    }

    public Class<?> getBeanType() {
        return beanType;
    }
}
